package pl.pw.gis.gc_sa.utils;

import java.util.HashMap;
import java.util.Map;

import pl.pw.gis.gc_sa.data.Graph;
import pl.pw.gis.gc_sa.data.Vertex;

/**
 * Klasa zawierajaca same statyczne metody wykorzystywane przez rozne klasy w
 * aplikacji
 * 
 * @author Lukasz
 * 
 */
public class Utils {
    public static void log(String s) {
        System.out.println(s);
    }

    /**
     * Zwraca koszt zgodny z arytkulem metoda pelnego przegladu (zlozonosc n^2)
     * 
     * @param colorsArray
     *            tablica przypisanych kolorow
     * @param graph
     *            graf
     * @return koszt
     */
    public static int naiveArticleCostFunction(int[] colorsArray, Graph graph) {
        Map<Integer, Integer> colorsMap = getColorsMap(colorsArray);

        int cost = 0;
        for (Integer color : colorsMap.keySet()) {
            int colorCount = colorsMap.get(color);
            cost -= colorCount * colorCount;

            int conflictsCount = getNoConflicts(colorsArray, color, graph);

            // Konflikty liczone dwa razy, dlatego
            // 2* colorCount * (conflicts /2)
            cost += colorCount * conflictsCount;
        }

        return cost;
    }

    /**
     * Zwraca liczbe konfliktow dla danej klasy (koloru)
     * 
     * @param colorsArray
     *            tablica przypisanych kolorow
     * @param color
     *            dla jakiego koloru konflity
     * @param graph
     *            graf
     * @return liczba konfliktow
     */
    public static int getNoConflicts(int[] colorsArray, int color, Graph graph) {
        int conflictsCount = 0;
        for (int i = 0; i < colorsArray.length; i++) {
            if (colorsArray[i] == color) {
                for (Vertex adj : graph.getAdjacent(i))
                    if (colorsArray[adj.getId()] == color) conflictsCount++;
            }
        }
        return conflictsCount;
    }

    /**
     * Zwraca mape zliczajaca ilosc obiektow wszystkich klas
     * 
     * @param colorsArray
     *            tablica przypisanych kolorow
     * @return haszmapa z licznoscia klas
     */
    public static Map<Integer, Integer> getColorsMap(int[] colorsArray) {
        Map<Integer, Integer> colorsMap = new HashMap<Integer, Integer>();
        for (int color : colorsArray) {
            if (!colorsMap.containsKey(color))
                colorsMap.put(color, 1);
            else {
                Integer prevVal = colorsMap.get(color);
                colorsMap.put(color, prevVal + 1);
            }
        }
        return colorsMap;
    }
}
